<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>原型&原型链</title>
</head>

<body>
    <script>
        /* 原型 */
        (function () {
            // console.log(Date.prototype);
            // F2快捷更名
            function Fun() {
            }
            // 往fun原型中添加test方法
            Fun.prototype.test = function () {
                console.log("执行test()");
            }
            console.log(Fun.prototype);
            Fun.prototype.test();
            console.log(Fun.prototype.constructor === Fun);

            var fun = new Fun();
            fun.test();
            console.log(fun.__proto__);
            // console.log(fun.prototype);  --不存在undefined
            console.log(fun.__proto__ === Fun.prototype);
        })();

        /* 原型链 */
        (function () {
            console.log("原型链");

            function Fn() {
                this.test1 = function () {
                    console.log("test1()");
                };
            }
            function Fn2() {
                console.log("test");
            }
            console.log(Fn.prototype);  //此时有test2属性但无实际内容
            Fn.prototype.test2 = function () {
                console.log("test2()");
            };
            console.log(Fn.prototype); //此时加入test2方法
            var fn = new Fn();
            fn.test1();
            fn.test2();
            // fn.test3();
            console.log(Fn.prototype.__proto__ === Object.prototype);
            console.log(Object.prototype.__proto__ === null);
            console.log(Function.prototype === Function.__proto__);
            console.log("I'm " + (Fn.__proto__ === Fn2.__proto__) + ", " + (Fn.__proto__ === Function.prototype));
            //所有函数的隐式原型都是Function.prototype, 因为所有函数都是Functio的实例, var fun = new Function()
            console.log(Fn.prototype instanceof Object); //true
            console.log(Object.prototype instanceof Object); //false
            console.log(Object.prototype.__proto__); //null

            function Fnn() {
            }
            Fnn.prototype.a = '111';

            var fn1 = new Fnn();
            console.log(fn1.a, fn1); //111 Fnn

            var fn2 = new Fnn();
            fn2.a = '222';
            console.log(fn2.a, fn2, fn2.__proto__.a); //222 Fnn{a: '222'} 111
            fn2.__proto__.a = '222';
            console.log(fn1.a); //222

            fn2.a = null;
            console.log(fn2.a); //null

            console.log(fn1 instanceof Fnn); //true
            console.log(fn1 instanceof Object); //true
            console.log(fn1 instanceof Function); //false
            console.log(Fnn instanceof Function); //true

            console.log(Object instanceof Function); //true
            console.log(Object instanceof Object); //true
            console.log(Function instanceof Function); //true
            console.log(Function instanceof Object); //true
        })();

        /* 测试题 */
        // 1
        var A = function A(){}
        A.prototype.n = 1;
        var b = new A();
        A.prototype = {
            n: 2,
            m: 3
        };
        var c = new A();
        console.log(b.n, b.m, c.n, c.m); //1 undefined 2 3
        
        //2
        function F(){}
        Object.prototype.a = function(){
            console.log('a');
        };
        Function.prototype.b = function(){
            console.log('b');
        };
        var f = new F();
        f.a(); //a
        //f.b(); //is not a function 
        F.a(); //a
        F.b(); //b

        /*  f -> {} -> Object  */
        /*  F -> {} -> Object   
            F -> Function  */
        /*  f是构造函数F的实例对象, F是Funcion的实例&对象*/



    </script>
</body>

</html>